package com.aggregate.pay.saobei.support;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aggregate.pay.saobei.bean.AbstractData;
import com.aggregate.pay.saobei.bean.AbstractResult;
import com.aggregate.pay.saobei.support.utils.JSON;

/**
 * 接口API操作类抽象类
 * @author Moyq5
 * @date 2018年6月27日
 * @param <D>
 * @param <R>
 */
public abstract class AbstractClient<D extends AbstractData, R extends AbstractResult> implements Client<D, R> {

	private static Logger log = LoggerFactory.getLogger(AbstractClient.class);
	
	private Merch merch;
	
	public AbstractClient(Merch merch) {
		this.merch = merch;
	}
	
	@Override
	public R execute(D data) throws Throwable {
		data.setMerchantNo(merch.merchantNo());
		data.setTerminalId(merch.terminalId());
		data.setKeySign(sign(data));
		
		String reqBody = JSON.toJson(data);
		log.debug("请求参数：{}", reqBody);

		HttpClient client = Factory.getHttpClient();
		String resBody = client.post(getApiPath(), reqBody);
		log.debug("响应参数：{}", resBody);
		if (null == resBody || !resBody.startsWith("{")) {
			throw new Exception("渠道接口返回非JSON内容");
		}
		R r = JSON.toObject(resBody, getResultClass());

		if (r.getReturnCode().equals("01")) {
			String sign = sign(r);
			if (!sign.equalsIgnoreCase(r.getKeySign())) {
				log.warn("验签失败：源值[{}]!=实际值[{}]", r.getKeySign(), sign);
				throw new Exception("渠道接口返回内容验签失败");
			}
			log.debug("签名验证通过");
		}
		return r;
	}
	
	protected abstract Class<R> getResultClass();
	
	protected abstract String getApiPath();
	
	protected abstract String sign(D data);
	
	protected abstract String sign(R result);
	
}
